/*
 *  RingerSearch.cpp
 *  MetaThrift
 *
 *  Created by Ian Pye on 4/8/08.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 
   Returns a list of files matching a given search criteria.
 *
 */

// Thrift headers
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>

// Loggers
#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/helpers/exception.h>
#include <log4cxx/propertyconfigurator.h>

// My Headers
#include "RingerMetaServer.h"
#include "Ringer.h"
#include "RingerFS.h"
#include "FileUtil.h"
#include "NetworkUtil.h"
#include "MetaTest.h"
#include "SimHash.h"
#include "SimHashResults.h"

using namespace std;
using namespace facebook::thrift;
using namespace facebook::thrift::protocol;
using namespace facebook::thrift::transport;

using namespace ringer;
using namespace boost;

using namespace log4cxx;
using namespace log4cxx::helpers;

int main(int argc, char** argv) {
  
  set<rpath_t>::iterator it;
  RingerNetworkArgs *net_args = new RingerNetworkArgs();
  net_args->mds_port = RINGER_DEFUALT_MDS_PORT;
  net_args->self_port = RINGER_DEFUALT_SELF_PORT;
  net_args->mds_host = RINGER_DEFAULT_MDS_HOST;
  net_args->self_host = RINGER_DEFAULT_SELF_HOST;
  net_args->local_cache_dir = RINGER_L_CACHE;
  int search_argc = argc;
  char **search_argv = argv;
  search_argc = parse_ringer_args(argc, argv, net_args, search_argv);
  
  ringer_init_network(net_args, true); 
  
  //now, try setting up the logger
  // Set up a simple configuration that logs on the console.
	try{
		PropertyConfigurator::configure(RINGER_LOGGING_CONFIG);		
	}
	catch(log4cxx::helpers::Exception &e){
		cerr << "Error: Could not set up the logger: " << e.getMessage() << endl;
	}
  
  RingerSearch rs_new;
  CTags* pTags = new CTags(const_cast<char *> (net_args->simhash_tags_file.c_str()));
	CResults* pResults = new CResults(pTags->GetTagCount());
  
  for (int i=1; i<search_argc; i++){
    cout << "Searching For: " << search_argv[i];
    if (IsDir(search_argv[i])){
      cout << " As SimHash of Dir." << endl;  
      if (ProcessDir(search_argv[i], pTags, pResults)){
        for (int j = 0; j < pTags->GetKeyCount(); j++){
          rs_new.simhash_keys.push_back(pResults->ComputeHashKey(pTags, j, USE_EXT_SIMHASH));
        }
      }
    } else if(IsFile(search_argv[i])){
      cout << " As SimHash of File." << endl;  
      if (ProcessFile(search_argv[i], pTags, pResults)){
        for (int j = 0; j < pTags->GetKeyCount(); j++){
          rs_new.simhash_keys.push_back(pResults->ComputeHashKey(pTags, j, USE_EXT_SIMHASH));
        }
      }
    } else {
      cout << " As a search tag." << endl; 
      rs_new.search_terms.insert(search_argv[i]);
    }
  }
  
  set<rpath_t> results;  
  
  ringer_client_search(results, rs_new);
  
  cout << "Results:" << endl;
  for (it=results.begin(); it!=results.end(); it++){
    cout << *it << endl;
  }
  
  ringer_close_network();  
  
  return 0;
}
